package com.huluobo.jetpackkotlindemo2006a.paging

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import androidx.paging.*
import com.huluobo.jetpackkotlindemo2006a.paging.db.AppDatabase
import com.huluobo.jetpackkotlindemo2006a.paging.db.RepoMediator
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

/**
 * Created by lc on 2023/2/23.
 */
class PagingViewModel : ViewModel() {
    fun getPagingData(): Flow<PagingData<Repo>> {
        return Repository.getPagingData().cachedIn(viewModelScope)
    }

    fun getPagingData2(context: Context): LiveData<PagingData<Repo>> =
        Repository.getPagingData2(context).cachedIn(viewModelScope).asLiveData()
}

//实现网络请求
object Repository {
    const val PAGE_SIZE = 5
    private val service = ApiService.create()
    private val db = AppDatabase.instance
    fun getPagingData(): Flow<PagingData<Repo>> {
        //prefetchDistance 表示距离底部多少条数据开始预加载
        //设置为0表示滑动到底部才加载,默认值为当前分页的大小
        //如果想让用户对加载无感,则适当增加这个值即可,比如现在咱们设置的5倍大小
        //PagingConfig是页面加载的配置文件,pageSize一次加载多少条
        return Pager(
            config = PagingConfig(pageSize = PAGE_SIZE, prefetchDistance = PAGE_SIZE * 5),
            pagingSourceFactory = {
                RepoPagingSource(
                    service
                )
            }).flow
    }

    private val pagingConfig = PagingConfig(
        //每页显示的数据的大小
        pageSize = PAGE_SIZE,
        //开启占位符
        enablePlaceholders = true,
        //预刷新的距离,距离最后一个item多远时加载数据
        //预加载默认值也是PAGE_SIZE
        prefetchDistance = PAGE_SIZE * 5,
        //初始化时加载的数量,默认是PAGE_SIZE *3
        initialLoadSize = PAGE_SIZE
    )

    @OptIn(ExperimentalPagingApi::class)
    fun getPagingData2(context: Context): Flow<PagingData<Repo>> {
        return Pager(
            config = pagingConfig,
            remoteMediator = RepoMediator(service, db, context)
        ) {
            //从数据库中拿到所有的数据
            db.repoDao().get()
        }.flow.map { pagingData ->
            pagingData.map {
                Repo(
                    id = it.id.toString(),
                    name = it.name,
                    description = it.description,
                    starCount = it.starCount
                )
            }
        }
    }

}